package com.study.juc;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

public class EventQueue<T> {
    
    
    private LinkedList<T> eventList ;
    
    private final int maxSize;
    
    private final  static int DEFAULT_MAX_EVENT = 10;
    public EventQueue() {
        this(DEFAULT_MAX_EVENT);
    }
    public EventQueue(int size) {
        maxSize = size;
        eventList = new LinkedList<T>();
    }
    
    
    public T take()  {
        synchronized (eventList){
            while(eventList.size()<=0){
                try {
                    eventList.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            T t = eventList.removeFirst();
            eventList.notifyAll();
            return t;
        }
    }
    
    public void offer(T element){
        synchronized (eventList){
            while (eventList.size()>=maxSize){
                try {
                    eventList.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            eventList.addLast(element);
            eventList.notifyAll();
        }
    }

    public static void main(String[] args) {

        EventQueue<Runnable> runnableEventQueue = new EventQueue<>();

        IntStream.range(0,10).parallel().forEach(i->{
            Runnable a = new Runnable() {
                @Override
                public void run() {
                    int j =0;
                    for(;j<10;){
                        try {
                            j++;
                            TimeUnit.SECONDS.sleep(2);
                            System.out.println("runable"+i+Thread.currentThread().getName());
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                }
            };
            runnableEventQueue.offer(a);
        });
        
        for(int i=0;i<5;i++){
            new Thread(()->{
                Runnable take = runnableEventQueue.take();
                take.run();
            }).start();
        }
        
        
    }
}
